package com.augurit.common.dao;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Repository;

import com.augurit.common.base.dao.BaseDao;
import com.augurit.common.constant.OrgConstant;
import com.augurit.common.entity.AcPartyRole;
import com.augurit.common.entity.OmGroup;
import com.augurit.common.entity.OmOrg;
import com.augurit.common.entity.OmPosition;
import com.augurit.common.system.convert.AcRoleConverter;
import com.augurit.common.system.convert.OmOrgConverter;
import com.augurit.common.system.convert.OmPositionConverter;
import com.augurit.common.system.web.org.form.AcPartyRoleForm;
import com.augurit.common.system.web.org.form.OmGroupForm;
import com.augurit.common.system.web.org.form.OmOrgForm;
import com.augurit.common.system.web.org.form.OmPositionForm;
import com.augurit.common.util.HqlUtils;
import com.augurit.common.util.lang.CollectionUtils;

/**
 * 组织对象角色关联DAO类
 */
@Repository
public class AcPartyRoleDao extends BaseDao<AcPartyRole, Long> {

	/**
	 * 保存应用系统Form对象
	 * @param form 应用系统Form对象
	 */
	public void save(AcPartyRoleForm form){
		
		if(form != null){
			AcPartyRole entity = null;
			
			//准备VO对象
			if(form != null && form.getPrId() != null){
				entity = this.get(form.getPrId());
			}else{
				entity = new AcPartyRole();
			}
			
			//属性值转换
			AcRoleConverter.convertToEntity(form, entity);
			
			//保存
			super.save(entity);
			
			//回填ID属性值
			form.setPrId(entity.getPrId());
		}
	}
	
	/**
	 * 获取指定角色下的机构列表
	 * @param roleId
	 * @return
	 */
	public List<OmOrgForm> getOrgsByRoleId(Long roleId){
		if(roleId != null ){
			String hql = "select os from AcPartyRole ps, OmOrg os where ps.roleId = ? and ps.partyType = ? and ps.partyId = os.orgId";
			List values = new ArrayList();
			values.add(OrgConstant.PARTY_TYPE_ORG);
			values.add(roleId);
			List<OmOrg> list = this.find(hql, values);
			return OmOrgConverter.convertToFormList(list);
		}
		return null;
	}
	
	/**
	 * 获取与指定角色不关联的机构列表
	 * @param roleId
	 * @return
	 */
	public List<OmOrgForm> getOrgsNotAssociateRole(Long roleId){
		if(roleId != null){
			String hql = "select os from OmOrg os where os.orgId not in "
				         + "( select ps.partyId from AcPartyRole ps where ps.partyType = ? and ps.roleId = ?)";
			List values = new ArrayList();
			values.add(OrgConstant.PARTY_TYPE_ORG);
			values.add(roleId);
			List<OmOrg> list = this.find(hql, values);
			return OmOrgConverter.convertToFormList(list);
		}
		return null;
	}
	
	/**
	 * 获取指定角色下的岗位列表
	 * @param roleId
	 * @return
	 */
	public List<OmPositionForm> getPositionsByRoleId(Long roleId){
		if(roleId != null ){
			String hql = "select os from AcPartyRole ps,OmPosition os where ps.partyType = ? and ps.roleId = ? and ps.partyId = os.posId";
			List values = new ArrayList();
			values.add(OrgConstant.PARTY_TYPE_POSITION);
			values.add(roleId);
			List<OmPosition> list = this.find(hql,values);
			return OmPositionConverter.convertToFormList(list);
		}
		return null;
	}
	
	/**
	 * 获取不与指定角色关联的岗位列表
	 * @param roleId
	 * @return
	 */
	public List<OmPositionForm> getPositionsNotAssociateRole(Long roleId){
		if(roleId != null){
			
			String hql = "select os from OmPosition os where os.posId not in "
				         + "( select ps.partyId from AcPartyRole ps where ps.partyType = ? and ps.roleId = ?)";
			List values = new ArrayList();
			values.add(OrgConstant.PARTY_TYPE_POSITION);
			values.add(roleId);
			List<OmPosition> list = this.find(hql,values);
			return OmPositionConverter.convertToFormList(list);
		}
		return null;
	}
	
	/**
	 * 获取指定角色下的工作组列表
	 * @param roleId
	 * @return
	 */
	public List<OmGroupForm> getGroupsByRoleId(Long roleId){
		if(roleId != null ){
			String hql = "select os from AcPartyRole ps,OmGroup os where ps.partyType = ? and ps.roleId = ? and ps.partyId = os.groupId";
			List values = new ArrayList();
			values.add(OrgConstant.PARTY_TYPE_GROUP);
			values.add(roleId);
			List<OmGroup> list = this.find(hql,values);
			//return OmGroupConverter.convertToFormList(list);
		}
		return null;
	}
	
	/***
	 * 获取不与指定角色关联的工作组列表
	 * @param roleId
	 * @return
	 */
	public List<OmGroupForm> getGroupsNotAssociateRole(Long roleId){
		if(roleId != null){
			String hql = "select os from OmGroup os where os.groupId not in"
				         + "( select ps.partyId from AcPartyRole ps where ps.partyType = ? and ps.roleId = ?)";
			List values = new ArrayList();
			values.add(OrgConstant.PARTY_TYPE_GROUP);
			values.add(roleId);
			List<OmGroup> list = this.find(hql,values);
			//return OmGroupConverter.convertToFormList(list);
		}
		return null;
	}
	
	/**
	 * 获取与指定角色关联的机构id数组
	 * @param roleId 角色id
	 * @return 机构id数组
	 */
	public Long[] getOrgIdsByRole(Long roleId){
		if(roleId != null){
			return getPartyIdsByRole(roleId, OrgConstant.PARTY_TYPE_ORG);
		}
		return null;
	}
	
	/**
	 * 获取与指定角色关联的机构id数组
	 * @param roleId 角色id
	 * @return 机构id数组
	 */
	public Long[] getGroupIdsByRole(Long roleId){
		if(roleId != null){
			return getPartyIdsByRole(roleId, OrgConstant.PARTY_TYPE_GROUP);
		}
		return null;
	}
	/**
	 * 获取与指定角色关联的岗位id数组
	 * @param roleId 角色id
	 * @return 机构id数组
	 */
	public Long[] getPositionsIdsByRoleId(Long roleId){
		if(roleId != null){
			return getPartyIdsByRole(roleId, OrgConstant.PARTY_TYPE_POSITION);
		}
		return null;
	}
	
	/**
	 * 获取拥有指定角色的组织对象
	 * @param roleId 角色id
	 * @param partyType 组织的类型
	 * @return 组织id数组
	 */
	private Long[] getPartyIdsByRole(Long roleId,String partyType){
		if(roleId != null && partyType != null && partyType.trim().length() > 0){
			String hql = "select ps.partyId from AcPartyRole ps where roleId = ? and partyType = ?";
			List values = new ArrayList();
			values.add(roleId);
			values.add(partyType);
			List<Long> list = this.find(hql, values);
			return CollectionUtils.toLongArray(list);
		}
		return null;
		
	}

	/**
	 * 获取与组织对象关联的角色ID集合
	 * @param partyType 组织对象类型
	 * @param partyId 组织对象主键ID
	 * @return
	 */
	public List<Long> getRoleIdList(String partyType, Long partyId){
		return (List<Long>)partSelectAcPartyRole(partyType, partyId, "roleId");
	}
	
	public Long[] getRoleIds(String partyType, Long partyId){
		List<Long> list = partSelectAcPartyRole(partyType, partyId, "roleId");
		return CollectionUtils.toLongArray(list);
	}
	
	public Long[] getRoleIds(String partyType, Long[] partyIds){
		List<Long> list = partSelectAcPartyRole(partyType, partyIds, "roleId");
		return CollectionUtils.toLongArray(list);
	}
	
	private List partSelectAcPartyRole(String partyType, Long partyId, String entityProperty){
		if(partyType != null && partyType.trim().length() > 0 && partyId != null){
			String hql = "select " 
							+ (entityProperty != null && entityProperty.trim().length() > 0 ? "ps." + entityProperty : "ps") 
							+ " from AcPartyRole ps where ps.partyType = ? and ps.partyId = ?";
			List values = new ArrayList();
			values.add(partyType);
			values.add(partyId);
			
			return this.find(hql,values);
		}else
			return null;
	}
	
	private List partSelectAcPartyRole(String partyType, Long[] partyIds, String entityProperty){
		if(partyType != null && partyType.trim().length() > 0 && partyIds != null && partyIds.length > 0){
			String hql = "select " 
							+ (entityProperty != null && entityProperty.trim().length() > 0 ? "ps." + entityProperty : "ps") 
							+ " from AcPartyRole ps where ps.partyType = ? and " + HqlUtils.buildOrCondition("ps", "partyId", partyIds);
			List values = new ArrayList();
			values.add(partyType);
			
			return this.find(hql,values);
		}else
			return null;
	}
	
	/**
	 * 删除角色关联的机构、岗位等
	 * @param roleId 角色id
	 */
	public void deleteByRoleId(Long roleId){
		if(roleId != null){
			String hql = "from AcPartyRole ps where ps.roleId = ?";
			List values = new ArrayList();
			values.add(roleId);
			List<AcPartyRole> list = this.find(hql, values);
			
			if(list != null && list.size() > 0)	
				this.delete(list);
		}
	}
	
	/**
	 * 把指定的角色分配给指定机构
	 * @param roleId
	 * @param orgId
	 */
	public void assignRoleToOrg(Long roleId, Long orgId){
		if(roleId != null && orgId != null){
			Long[] ids = this.getPrIds(OrgConstant.PARTY_TYPE_ORG, orgId, roleId);
			if(ids == null){
				AcPartyRole entity = new AcPartyRole();
				entity.setRoleId(roleId);
				entity.setPartyType(OrgConstant.PARTY_TYPE_ORG);
				entity.setPartyId(orgId);
				this.save(entity);
			}
		}
	}
	
	/**
	 * 把指定的角色分配给指定工作组
	 * @param groupId
	 * @param groupId
	 */
	public void assignRoleToGroup(Long roleId, Long groupId){
		if(roleId != null && groupId != null){
			Long[] ids = this.getPrIds(OrgConstant.PARTY_TYPE_GROUP, groupId, roleId);
			if(ids == null){
				AcPartyRole entity = new AcPartyRole();
				entity.setRoleId(roleId);
				entity.setPartyType(OrgConstant.PARTY_TYPE_GROUP);
				entity.setPartyId(groupId);
				this.save(entity);
			}
		}
	}
	
	/**
	 * 把指定的角色分配给指定职位
	 * @param roleId
	 * @param posId
	 */
	public void assignRoleToPosition(Long roleId, Long posId){
		if(roleId != null && posId != null){
			Long[] ids = this.getPrIds(OrgConstant.PARTY_TYPE_POSITION, posId, roleId);
			if(ids == null){
				AcPartyRole entity = new AcPartyRole();
				entity.setRoleId(roleId);
				entity.setPartyType("POSITION");
				entity.setPartyId(posId);
				this.save(entity);
			}
		}
	}
	
	/**
	 * 获取与组织对象及指定角色的主键集合
	 * @param partyType
	 * @param partyId
	 * @param roleId
	 * @return
	 */
	private Long[] getPrIds(String partyType, Long partyId, Long roleId){
		if(partyType != null && partyType != null && roleId != null){
			String hql = "select ps.prId from AcPartyRole ps where partyType = ? and partyId = ? and roleId = ? ";
			List values = new ArrayList();
			values.add(partyType);
			values.add(partyId);
			values.add(roleId);
			
			List<Long> list = this.find(hql,values);
			return CollectionUtils.toLongArray(list);
		}
		return null;
	}
	/**
	 * 删除指定机构与角色的关联
	 * @param roleId
	 * @param orgId
	 */
	public void disAssociateRoleFromOrg(Long roleId, Long orgId){
		if(roleId != null && orgId != null){
			Long[] prIds = this.getPrIds(OrgConstant.PARTY_TYPE_ORG, orgId, roleId);
			if(prIds != null && prIds.length > 0){
				this.delete(prIds);
			}
		}
	}
	
	/**
	 * 删除指定岗位与角色的关联
	 * @param roleId
	 * @param posId
	 */
	public void disAssociateRoleFromPos(Long roleId, Long posId){
		if(roleId != null && posId != null){
			Long[] prIds = this.getPrIds(OrgConstant.PARTY_TYPE_POSITION, posId, roleId);
			
			if(prIds != null && prIds.length > 0){
				this.delete(prIds);
			}
		}
	}
	
	/**
	 * 删除指定工作组与角色的关联
	 * @param roleId
	 * @param groupId
	 */
	public void disAssociateRoleFromGroup(Long roleId, Long groupId){
		if(roleId != null && groupId != null){
			Long[] prIds = this.getPrIds(OrgConstant.PARTY_TYPE_GROUP, groupId, roleId);
			
			if(prIds != null && prIds.length > 0){
				this.delete(prIds);
			}
		}
	}
}
